home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 November / EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso / earcd / program / gcc / ixemul-4.lha / ixemul-41.4 / stdlib / system.c < prev   
C/C++ Source or Header  |  1995-05-28  |  4KB  |  134 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #define KERNEL
  21. #include "ixemul.h"
  22. #include "kprintf.h"
  23. #include <sys/wait.h>
  24. #include <ctype.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27.  
  28. /* 2.0 support */
  29. #include <utility/tagitem.h>
  30. #include <dos/dostags.h>
  31.  
  32.  
  33. #define    PRB_CLI        0L    /* Do a CLI, not a shell    */
  34. #define    PRB_BACKGROUND    1L    /* Background shell        */
  35. #define    PRB_EXECUTE    2L    /* Do as EXECUTE...        */
  36. #define    PRB_INTERACTIVE    3L    /* Run an interactive shell    */
  37. #define    PRB_FB        7L    /* Alt function bit...        */
  38.  
  39. #define    PRF_CLI        (1L << PRB_CLI)
  40. #define    PRF_BACKGROUND    (1L << PRB_BACKGROUND)
  41. #define    PRF_EXECUTE    (1L << PRB_EXECUTE)
  42. #define    PRF_INTERACTIVE    (1L << PRB_INTERACTIVE)
  43. #define    PRF_FB        (1L << PRB_FB)
  44.  
  45. #define    EXECUTE_ME        (PRF_FB|PRF_BACKGROUND|PRF_EXECUTE)    /* aptly named, doncha think?    */
  46.  
  47. #define SYSSTACKSIZE (4096)    /* The typical default system stack size. */
  48. #define STACKNAME ("IXSTACK")    /* Environment variable for minimum stack size */
  49. #define STACKSIZE (250000)    /* Minimum to use if no IXSTACK and stack is SYSSTACKSIZE */
  50.  
  51. #define alloca __builtin_alloca
  52.  
  53. #undef MAX
  54. #define    MAX(a,b) (((a)>(b))?(a):(b))
  55.  
  56. int
  57. system (const char *cmd)
  58. {
  59.   int rc = -1, err = 0;
  60.   int stack_size;
  61.   int env_stack_size = 0;
  62.   struct CommandLineInterface *CLI;
  63.   struct Process *me;
  64.   extern struct ixemul_base *ixemulbase;
  65.   int omask;
  66.   char *temp;
  67.  
  68.   if (cmd == NULL)
  69.     return 1;
  70.   /* I retry with our new signal mechanism ;-) */
  71.   omask = syscall (SYS_sigsetmask, ~0);
  72.  
  73.   me = (struct Process *)FindTask(0);
  74.   CLI = BTOCPTR (me->pr_CLI);
  75.  
  76.   /* Find out what the current stack size is.  If there is an environment
  77.      variable (STACKNAME) that sets the minimum stack, and that stack value
  78.      is at least as large as the system default stack value (SYSSTACKSIZE),
  79.      then use either that value or the current value, whichever is larger.
  80.      Otherwise, if the current stack value is the system default, which
  81.      indicates the user has not set a specific stack, then default to a
  82.      value (STACKSIZE) that should be large enough for most cases. */
  83.  
  84.   stack_size = CLI ? CLI->cli_DefaultStack * 4 : me->pr_StackSize;
  85.   if ((temp = getenv (STACKNAME)) != NULL && (env_stack_size = atoi (temp)) >= SYSSTACKSIZE)
  86.     stack_size = MAX (stack_size, env_stack_size);
  87.   else if (stack_size <= SYSSTACKSIZE)
  88.     stack_size = STACKSIZE;
  89.  
  90.   /* limited support to allow starting of files in the current directory
  91.    * with `./foo'. The better approach would use the __plock() trick to
  92.    * parse the command, LoadSeg it. But then this approach would have to
  93.    * do the whole redirection stuff on its own.. */
  94.   while (isspace (*cmd)) cmd++;
  95.   while (cmd[0] == '.' && cmd[1] == '/') cmd += 2;
  96.   /* convert absolute path names if enabled in ixemulbase */
  97.   if (ixemulbase->ix_translate_slash && cmd[0] == '/')
  98.     {
  99.      char *path_sep = NULL;
  100.  
  101.      cmd++;
  102.      if (path_sep = strchr (cmd, '/'))  *path_sep = ':';
  103.     }
  104.  
  105. if (1)
  106.     {
  107.       struct TagItem tags [] = {
  108.     /* a stack of 4K is generally ways too small.. */
  109.     { NP_StackSize, stack_size, },
  110.     { TAG_END, 0, }
  111.       };
  112.  
  113.       rc = SystemTagList ((UBYTE *)cmd, tags);
  114.       err = __ioerr_to_errno (IoErr ());
  115.  
  116.   syscall (SYS_sigsetmask, omask);
  117.  
  118.   if (rc > 128)
  119.     {
  120.       errno = EINTR;
  121.     }
  122.   else 
  123.     {
  124.       errno = err;
  125.     }
  126.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  127.  
  128.   /* according to the BSD manual, system() should return the `exit status'
  129.    * of the shell, the implementation returns the wait-status. So I return
  130.    * an artificial wait status for now ... */
  131.   return (rc >= 128) ? W_EXITCODE (0, rc & 0x7f) : W_EXITCODE (rc, 0);
  132.     }
  133. }
  134.